﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data;
using DataBaseConnection;
using System.Collections;

namespace DataEntity
{
    /// <summary>
    /// 主键属性
    /// </summary>
    public class PrimaryKeyAttribute : Attribute
    {
        
    }

    /// <summary>
    /// 递增属性
    /// </summary>
    public class AutoKeyAttribute : Attribute
    {
        
    }

    /// <summary>
    /// 快速表操作命令
    /// </summary>
    public class Common
    {
        /// <summary>
        /// 该对象是否存在主键
        /// </summary>
        /// <param name="FieldObject">字段成员</param>        
        public static bool ExistsPrimaryKey(FieldInfo FieldObject)
        {
            object[] attrs = FieldObject.GetCustomAttributes(typeof(PrimaryKeyAttribute), true);
            return (attrs != null && attrs.Length != 0);
        }

        /// <summary>
        /// 该对象是否存在递增
        /// </summary>
        /// <param name="FieldObject">字段成员</param>        
        public static bool ExistsAutoKey(FieldInfo FieldObject)
        {
            object[] attrs = FieldObject.GetCustomAttributes(typeof(AutoKeyAttribute), true);
            return (attrs != null && attrs.Length != 0);
        }

        /// <summary>
        /// 用一个分隔符将一个数组组合成字符串
        /// </summary>
        /// <param name="ArrayObj">数组</param>
        /// <param name="compart">分隔符</param>
        /// <returns>如：a,b,c</returns>
        public static string UniteArray(string[] ArrayObj, string compart)
        {
            if (ArrayObj == null && ArrayObj.Length == 0) { return string.Empty; }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < ArrayObj.Length; i++)
            {
                sb.Append(ArrayObj[i]).Append((i == ArrayObj.Length - 1) ? string.Empty : compart);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 执行自定义{添加、修改、删除}
        /// </summary>        
        /// <param name="Sql">sql语句</param>
        /// <param name="whereKeys">sql条件里的变量</param>
        /// <param name="whereValues">条件变量对应的值</param> 
        /// <param name="commType">sql类型</param>
        /// <returns>影响行数</returns>
        public static int ExecuteNonQuery(string Sql, string[] whereKeys, object[] whereValues, CommandType commType)
        {
            PConnOrder co = CSelectDataBase.GetDataBase();
            List<IDataParameter> paras = new List<IDataParameter>();
            if (whereKeys != null && whereValues != null)
            {
                try
                {
                    for (int i = 0; i < whereKeys.Length; i++)
                    {
                        paras.Add(co.GetNewParameter(whereKeys[i], whereValues[i]));
                    }
                }
                catch (IndexOutOfRangeException ex)
                {
                    throw new Exception("SQL语句里的@变量与传递参数数量不一致");
                }
            }
            //执行语句
            int result = co.ExecuteNonQuery(Sql, paras.ToArray(), commType);
            co.ConnectionClose();
            return result;
        }

        public static int ExecuteNonQuery(string Sql, string[] whereKeys, object[] whereValues)
        {
            return ExecuteNonQuery(Sql, whereKeys, whereValues, CommandType.Text);
        }

        /// <summary>
        /// 获取单个字段
        /// </summary>
        /// <param name="Sql">sql语句</param>
        /// <param name="whereKeys">sql条件里的变量</param>
        /// <param name="whereValues">条件变量对应的值</param> 
        /// <param name="commType">sql类型</param>
        /// <returns>返回一行一列的字段</returns>
        public static object ExecuteScalar(string Sql, string[] whereKeys, object[] whereValues, CommandType commType)
        {
            PConnOrder co = CSelectDataBase.GetDataBase();
            List<IDataParameter> paras = new List<IDataParameter>();
            if (whereKeys != null && whereValues != null)
            {
                try
                {
                    for (int i = 0; i < whereKeys.Length; i++)
                    {
                        paras.Add(co.GetNewParameter(whereKeys[i], whereValues[i]));
                    }
                }
                catch (IndexOutOfRangeException ex)
                {
                    throw new Exception("SQL语句里的@变量与传递参数数量不一致");
                }
            }
            //执行语句
            object result = co.ExecuteScalar(Sql, paras.ToArray(), commType);
            co.ConnectionClose();
            return result;
        }

        public static T ExecuteScalar<T>(string Sql, string[] whereKeys, object[] whereValues, CommandType commType)
        {
            object rs = ExecuteScalar(Sql, whereKeys, whereValues, commType);

            T s_t = default(T);

            if (rs != null)
            {
                try { s_t = (T)Convert.ChangeType(rs, typeof(T)); } catch { }
            }
            return s_t;
        }

        public static T ExecuteScalar<T>(string Sql, string[] whereKeys, object[] whereValues)
        {
            return ExecuteScalar<T>(Sql, whereKeys, whereValues, CommandType.Text);
        }

        public static object ExecuteScalar(string Sql, string[] whereKeys, object[] whereValues)
        {
            return ExecuteScalar(Sql, whereKeys, whereValues, CommandType.Text);
        }

        /// <summary>
        /// 执行自定义{查询结果}
        /// </summary>        
        /// <param name="Sql">sql语句</param>
        /// <param name="whereKeys">sql条件里的变量</param>
        /// <param name="whereValues">条件变量对应的值</param> 
        /// <param name="commType">sql类型</param>
        /// <returns>表集合</returns>
        public static DataSet ExecuteDataSet(string Sql, string[] whereKeys, object[] whereValues, CommandType commType)
        {
            PConnOrder co = CSelectDataBase.GetDataBase();
            List<IDataParameter> paras = new List<IDataParameter>();
            if (whereKeys != null && whereValues != null)
            {
                try
                {
                    for (int i = 0; i < whereKeys.Length; i++)
                    {
                        paras.Add(co.GetNewParameter(whereKeys[i], whereValues[i]));
                    }
                }
                catch (IndexOutOfRangeException ex)
                {
                    throw new Exception("SQL语句里的@变量与传递参数数量不一致");
                }
            }
            //执行语句
            DataSet result = co.ExecuteDataSet(Sql, paras.ToArray(), commType);
            co.ConnectionClose();
            return result;
        }
        /// <summary>
        /// 执行自定义{查询结果}
        /// </summary>        
        public static DataSet ExecuteDataSet(string Sql, string[] whereKeys, object[] whereValues)
        {
            return ExecuteDataSet(Sql, whereKeys, whereValues, CommandType.Text);
        }

        /// <summary>
        /// 执行自定义{查询结果}
        /// </summary>        
        public static List<T> ExecuteList<T>(string Sql, string[] whereKeys, object[] whereValues)
        {
            DataTable dt = ExecuteDataSet(Sql, whereKeys, whereValues, CommandType.Text).Tables[0];
            if (dt == null || dt.Rows.Count == 0) { return null; }

            List<T> array = new List<T>();
            foreach (DataRow dr in dt.Rows)
            {
                array.Add((T)Convert.ChangeType(dr[0], typeof(T)));
            }
            return array;
        }

        /// <summary>
        /// 查询分页
        /// </summary>
        /// <param name="sqlText">查询语句</param>        
        /// <param name="Primary">主键</param>
        /// <param name="Orderby">排序</param>
        /// <param name="MaxRows">每页行数</param>
        /// <param name="CurrPage">当前页数</param>
        /// <returns>Tables[0]:查询数据 Tables[1].Rows[0][0]:总数据量</returns>
        public static DataSet ExecuteSplitPage(string Sql, string Primary, string Orderby, int MaxRows, int CurrPage)
        {
            PConnOrder co = CSelectDataBase.GetDataBase();
            //执行语句
            DataSet result = co.SplitPage(Sql, Primary, Orderby, MaxRows, CurrPage);
            co.ConnectionClose();
            return result;
        }

        

        /// <summary>
        /// 快速查询一个实体对象
        /// </summary>
        /// <typeparam name="IDataEntity">实体类</typeparam>
        /// <param name="whereSql">sql条件语句</param>
        /// <param name="whereKeys">sql条件里的变量</param>
        /// <param name="whereValues">条件变量对应的值</param> 
        /// <returns>对应的实体对象</returns>
        public static IDataEntity Select<IDataEntity>(string whereSql, string[] whereKeys, object[] whereValues) where IDataEntity : new()
        {
            IDataEntity iobj = new IDataEntity();
            MethodInfo mi = iobj.GetType().GetMethod("Select", new Type[] { typeof(string), typeof(string[]), typeof(object[]) });
            if (mi != null) { mi.Invoke(iobj, new object[] { whereSql, whereKeys, whereValues }); }//调用该方法
            return iobj;
        }
        /// <summary>
        /// 快速查询实体对象数组
        /// </summary>
        /// <typeparam name="IDataEntity">实体类</typeparam>
        /// <param name="whereSql">sql条件语句</param>
        /// <param name="whereKeys">sql条件里的变量</param>
        /// <param name="whereValues">条件变量对应的值</param> 
        /// <returns>对应的实体对象数组</returns>
        public static IDataEntity[] SelectList<IDataEntity>(string whereSql, string[] whereKeys, object[] whereValues) where IDataEntity : new()
        {
            DataTable dt = null;
            IDataEntity iobj = new IDataEntity();
            MethodInfo mi = iobj.GetType().GetMethod("SelectDataTable", new Type[] { typeof(string), typeof(string[]), typeof(object[]) });
            if (mi != null) { dt = (DataTable)mi.Invoke(iobj, new object[] { whereSql, whereKeys, whereValues }); }//调用该方法
            if (dt == null || dt.Rows.Count == 0) { return default(IDataEntity[]); }
            List<IDataEntity> ides = new List<IDataEntity>();
            foreach (DataRow dr in dt.Rows)
            {
                iobj = new IDataEntity();
                MethodInfo cmi = iobj.GetType().GetMethod("SetValues", new Type[] { typeof(DataRow) });
                if (cmi != null) { cmi.Invoke(iobj, new object[]{ dr }); }//调用该方法
                ides.Add(iobj);
            }
            return ides.ToArray();
        }
        /// <summary>
        /// 快速查询实体对象数组
        /// </summary>
        /// <typeparam name="IDataEntity">实体类</typeparam>
        /// <param name="whereSql">sql条件语句</param>
        /// <param name="whereKeys">sql条件里的变量</param>
        /// <param name="whereValues">条件变量对应的值</param> 
        /// <returns>对应的实体对象数组</returns>
        public static IDataEntity[] SelectList<IDataEntity>(string whereSql, string[] whereKeys, object[] whereValues, int topCount) where IDataEntity : new()
        {
            DataTable dt = null;
            IDataEntity iobj = new IDataEntity();
            MethodInfo mi = iobj.GetType().GetMethod("SelectDataTable", new Type[] { typeof(string), typeof(string[]), typeof(object[]), typeof(int) });
            if (mi != null) { dt = (DataTable)mi.Invoke(iobj, new object[] { whereSql, whereKeys, whereValues, topCount }); }//调用该方法

            return SelectList<IDataEntity>(dt);
        }

        public static IDataEntity[] SelectList<IDataEntity>(DataTable dt) where IDataEntity : new()
        {            
            if (dt == null || dt.Rows.Count == 0) { return default(IDataEntity[]); }
            List<IDataEntity> ides = new List<IDataEntity>();
            
            foreach (DataRow dr in dt.Rows)
            {
                IDataEntity iobj = new IDataEntity();
                MethodInfo cmi = iobj.GetType().GetMethod("SetValues", new Type[] { typeof(DataRow) });
                if (cmi != null) { cmi.Invoke(iobj, new object[] { dr }); }//调用该方法
                ides.Add(iobj);
            }
            return ides.ToArray();
        }

        /// <summary>
        /// 合并条件
        /// </summary>
        /// <param name="Condis">条件列表值</param>
        /// <param name="ColName">列名</param>
        /// <param name="IsChar">是否字符(加单引号)</param>
        /// <returns></returns>
        public static string UniteCondition(string[] Condis, string ColName, bool IsChar)
        {
            StringBuilder result = new StringBuilder();				//要输出的
            string IsString = (IsChar) ? "'" : "";	//什么数据类型,是否要加引号

            result.Append(ColName).Append(" IN (");
            //循环总数减1
            for (int i = 0; i < Condis.Length; i++)
            {
                result.Append(IsString).Append(Condis[i]).Append(IsString).Append(
                    (i < Condis.Length - 1) ? "," : string.Empty
                    );//是否最后一个                
            }
            //闭合
            result.Append(")");

            return result.ToString();
        }
    }    
}
